package com.fms.sys.controller;

import com.fms.common.vo.Result;
import com.fms.sys.entity.Billin;
import com.fms.sys.entity.Billout;
import com.fms.sys.service.IBillinService;
import com.fms.sys.service.IBilloutService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.*;
import java.util.stream.Collectors;

import com.fms.common.utils.JwtUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fms.sys.entity.Note;
import com.fms.sys.entity.Schedule;
import com.fms.sys.service.INoteService;
import com.fms.sys.service.IScheduleService;

@RestController
@RequestMapping("/dashboard")
public class DashboardController {

        @Autowired
        private IBillinService billinService;

        @Autowired
        private IBilloutService billoutService;

        @Autowired
        private INoteService noteService;

        @Autowired
        private IScheduleService scheduleService;

        @GetMapping("/summary")
        public Result<Map<String, Object>> getDashboardSummary() {
                Map<String, Object> data = new HashMap<>();

                // 1. 获取总收入
                List<Billin> allIncome = billinService.list();
                BigDecimal totalIncome = allIncome.stream()
                                .map(Billin::getAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);

                // 2. 获取总支出
                List<Billout> allExpense = billoutService.list();
                BigDecimal totalExpense = allExpense.stream()
                                .map(Billout::getAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);

                // 3. 计算结余
                BigDecimal balance = totalIncome.subtract(totalExpense);

                // 4. 获取本月收支
                YearMonth currentMonth = YearMonth.now();
                LocalDateTime monthStart = currentMonth.atDay(1).atStartOfDay();
                LocalDateTime monthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59);

                BigDecimal monthlyIncome = allIncome.stream()
                                .filter(bill -> {
                                        LocalDateTime consumeDate = bill.getConsumeDate();
                                        return consumeDate != null && !consumeDate.isBefore(monthStart)
                                                        && !consumeDate.isAfter(monthEnd);
                                })
                                .map(Billin::getAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);

                BigDecimal monthlyExpense = allExpense.stream()
                                .filter(bill -> {
                                        LocalDateTime consumeDate = bill.getConsumeDate();
                                        return consumeDate != null && !consumeDate.isBefore(monthStart)
                                                        && !consumeDate.isAfter(monthEnd);
                                })
                                .map(Billout::getAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);

                BigDecimal monthlyBalance = monthlyIncome.subtract(monthlyExpense);

                // 5. 获取最近6个月的收支趋势
                List<Map<String, Object>> trendData = new ArrayList<>();
                YearMonth start = currentMonth.minusMonths(5);
                for (int i = 0; i < 6; i++) {
                        YearMonth month = start.plusMonths(i);
                        LocalDateTime monthFirstDay = month.atDay(1).atStartOfDay();
                        LocalDateTime monthLastDay = month.atEndOfMonth().atTime(23, 59, 59);

                        BigDecimal monthIncome = allIncome.stream()
                                        .filter(bill -> {
                                                LocalDateTime consumeDate = bill.getConsumeDate();
                                                return consumeDate != null && !consumeDate.isBefore(monthFirstDay)
                                                                && !consumeDate.isAfter(monthLastDay);
                                        })
                                        .map(Billin::getAmount)
                                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                        BigDecimal monthExpense = allExpense.stream()
                                        .filter(bill -> {
                                                LocalDateTime consumeDate = bill.getConsumeDate();
                                                return consumeDate != null && !consumeDate.isBefore(monthFirstDay)
                                                                && !consumeDate.isAfter(monthLastDay);
                                        })
                                        .map(Billout::getAmount)
                                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                        Map<String, Object> monthData = new HashMap<>();
                        monthData.put("month", month.toString());
                        monthData.put("income", monthIncome);
                        monthData.put("expense", monthExpense);
                        trendData.add(monthData);
                }

                // 6. 获取支出分类统计
                Map<String, BigDecimal> expenseByCategory = allExpense.stream()
                                .collect(Collectors.groupingBy(
                                                Billout::getReason,
                                                Collectors.reducing(
                                                                BigDecimal.ZERO,
                                                                Billout::getAmount,
                                                                BigDecimal::add)));

                // 7. 获取最近交易记录
                List<Map<String, Object>> recentTransactions = new ArrayList<>();
                // 合并收入和支出记录
                allIncome.stream()
                                .map(bill -> {
                                        Map<String, Object> transaction = new HashMap<>();
                                        transaction.put("date", bill.getConsumeDate());
                                        transaction.put("type", "收入");
                                        transaction.put("amount", bill.getAmount());
                                        transaction.put("category", bill.getReason());
                                        transaction.put("description", bill.getTheme());
                                        return transaction;
                                })
                                .forEach(recentTransactions::add);

                allExpense.stream()
                                .map(bill -> {
                                        Map<String, Object> transaction = new HashMap<>();
                                        transaction.put("date", bill.getConsumeDate());
                                        transaction.put("type", "支出");
                                        transaction.put("amount", bill.getAmount());
                                        transaction.put("category", bill.getReason());
                                        transaction.put("description", bill.getTheme());
                                        return transaction;
                                })
                                .forEach(recentTransactions::add);

                // 按日期排序并只保留最近10条记录
                recentTransactions.sort(
                                (a, b) -> ((LocalDateTime) b.get("date")).compareTo((LocalDateTime) a.get("date")));
                if (recentTransactions.size() > 10) {
                        recentTransactions = recentTransactions.subList(0, 10);
                }

                // ========== 新增统计 ==========
                Long userId = JwtUtils.getCurrentUserId();
                // 我的待办
                LambdaQueryWrapper<Note> todoWrapper = new LambdaQueryWrapper<>();
                todoWrapper.eq(Note::getUserId, userId).eq(Note::getStatus, "未完成");
                int todoCount = (int) noteService.count(todoWrapper);
                // 今日日程
                java.time.LocalDate today = java.time.LocalDate.now();
                java.time.LocalDateTime startOfDay = today.atStartOfDay();
                java.time.LocalDateTime endOfDay = today.atTime(23, 59, 59);
                LambdaQueryWrapper<Schedule> todayScheduleWrapper = new LambdaQueryWrapper<>();
                todayScheduleWrapper.eq(Schedule::getCreateBy, userId)
                                .ge(Schedule::getStartTime, startOfDay)
                                .le(Schedule::getStartTime, endOfDay);
                int todayScheduleCount = (int) scheduleService.count(todayScheduleWrapper);
                // 本月统计
                // 直接复用前面已声明的currentMonth、monthStart、monthEnd
                LambdaQueryWrapper<Note> monthNoteDoneWrapper = new LambdaQueryWrapper<>();
                monthNoteDoneWrapper.eq(Note::getUserId, userId)
                                .ge(Note::getDeadline, monthStart)
                                .le(Note::getDeadline, monthEnd)
                                .eq(Note::getStatus, "已完成");
                int monthNoteDone = (int) noteService.count(monthNoteDoneWrapper);
                LambdaQueryWrapper<Note> monthNoteTodoWrapper = new LambdaQueryWrapper<>();
                monthNoteTodoWrapper.eq(Note::getUserId, userId)
                                .ge(Note::getDeadline, monthStart)
                                .le(Note::getDeadline, monthEnd)
                                .eq(Note::getStatus, "未完成");
                int monthNoteTodo = (int) noteService.count(monthNoteTodoWrapper);
                LambdaQueryWrapper<Schedule> monthScheduleDoneWrapper = new LambdaQueryWrapper<>();
                monthScheduleDoneWrapper.eq(Schedule::getCreateBy, userId)
                                .ge(Schedule::getEndTime, monthStart)
                                .le(Schedule::getEndTime, monthEnd)
                                .eq(Schedule::getStatus, 1);
                int monthScheduleDone = (int) scheduleService.count(monthScheduleDoneWrapper);
                LambdaQueryWrapper<Schedule> monthScheduleTodoWrapper = new LambdaQueryWrapper<>();
                monthScheduleTodoWrapper.eq(Schedule::getCreateBy, userId)
                                .ge(Schedule::getEndTime, monthStart)
                                .le(Schedule::getEndTime, monthEnd)
                                .eq(Schedule::getStatus, 0);
                int monthScheduleTodo = (int) scheduleService.count(monthScheduleTodoWrapper);
                Map<String, Object> monthStat = new HashMap<>();
                monthStat.put("noteDone", monthNoteDone);
                monthStat.put("noteTodo", monthNoteTodo);
                monthStat.put("scheduleDone", monthScheduleDone);
                monthStat.put("scheduleTodo", monthScheduleTodo);
                data.put("todoCount", todoCount);
                data.put("todayScheduleCount", todayScheduleCount);
                data.put("monthStat", monthStat);

                // 组装返回数据
                data.put("totalIncome", totalIncome);
                data.put("totalExpense", totalExpense);
                data.put("balance", balance);
                data.put("monthlyBalance", monthlyBalance);
                data.put("trendData", trendData);
                data.put("expenseByCategory", expenseByCategory);
                data.put("recentTransactions", recentTransactions);

                return Result.success(data);
        }
}
